/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package se.sll.itintegration.catalogue.offer.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import lombok.extern.slf4j.Slf4j;
import se.sll.itintegration.catalogue.offer.ejb.ContractEjb;
import se.sll.itintegration.catalogue.offer.entity.CVType;
import se.sll.itintegration.catalogue.offer.entity.ContractEntity;
import se.sll.service.catalogue.common.exception.ResourceNotFoundException;
import se.sll.service.catalogue.common.exception.ServiceCatalogueException;
import se.sll.service.catalogue.common.exception.ServiceErrorCode;
import se.sll.service.catalogue.common.exception.ServiceException;
import se.sll.service.catalogue.offers.api.model.Contract;
import se.sll.service.catalogue.offers.api.model.DatePeriod;
import se.sll.service.catalogue.offers.api.model.Id;
import se.sll.service.catalogue.offers.api.model.Type;
import se.sll.service.catalogue.offers.api.resource.ContractsService;

/**
 *
 * @author khaleddaham
 */
@Path("/contracts")
@Slf4j
@Stateless
public class ContractService implements ContractsService {

    @EJB private ContractEjb contractEjb;
    private static final String T_MEDIA_TYPE = "application/json; charset=UTF-8";

    /**
     * CRUD Operations
     * @return 
     * @throws se.sll.service.catalogue.common.exception.ServiceException
     */
    //@POST
    @Override
    public PostContractsResponse postContracts(Contract entity) throws ServiceException {
        log.info("create() ENTER");
        ContractEntity ce = convertContractModelToEntity(entity);
        contractEjb.create(ce);
        return PostContractsResponse.created();
    }

    @GET
    public List<ContractEntity> read() throws ServiceException {
        return null;
    }

    //@PUT
    @Override
    public PutContractsResponse putContracts(Contract entity) throws ServiceException {

        ContractEntity ce = (ContractEntity) contractEjb.findByAttributeValue("id", entity.getId().getExtension());
        if (ce != null) {
            try {
                Date now = new Date();
                ce.setUpdateTime(now);
                contractEjb.edit(ce);
            } catch (RuntimeException e) {
                log.error("ProductFacadeREST.update() Caught RuntimeException: " + e.getMessage());
                throw new ServiceCatalogueException();
            }
        } else {
            throw new ResourceNotFoundException(ServiceErrorCode.CONTRACT_NOT_FOUND, entity.getId());
        }


        return PutContractsResponse.jsonOK(entity);
    }

    @DELETE
    public List<ContractEntity> delete() throws ServiceException {
        return null;
    }

    /**
     * List all contracts
     *
     * @return
     * @throws se.sll.service.catalogue.common.exception.ServiceException
     */
    /*@GET
    @Consumes(T_MEDIA_TYPE)
    @Produces(T_MEDIA_TYPE)*/
    @Override
    public GetContractsResponse getContracts() throws ServiceException {
        log.info("list() ENTER");

        List<ContractEntity> result = null;
        try {
            result = contractEjb.findAll();
            if (log.isDebugEnabled() && result != null) {
                log.debug("Found {} Offers", new Object[]{result.size()});
//                for (OfferEntity offerEntity : result) {
//                    log.debug(offerEntity.toString());
//                }
            }
        } catch (RuntimeException e) {
            log.error("OfferService.list() Caught RuntimeException: " + e.getMessage());
            throw new ServiceCatalogueException();
        }

        log.info("OfferService.list() EXIT");
        return GetContractsResponse.jsonOK(convertContractEntityListToModel(result));
    }

    private List<Contract> convertContractEntityListToModel(List<ContractEntity> ceList) {
        List<Contract> response = new ArrayList<>();

        ceList.stream().map((ce) -> new Contract()
                .withId(new Id()
                        .withExtension(ce.getContractId())
                        .withRoot("RootForContractIds"))
                .withType(new Type()
                        .withCode(ce.getType().getCode())
                        .withCodeSystem("CodeSystemForContractTypes"))
                .withDatePeriod(new DatePeriod()
                        .withStart(ce.getStartDate())
                        .withEnd(ce.getEndDate()))).forEach((contract) -> {
                            response.add(contract);
        });

        return response;
    }

    private ContractEntity convertContractModelToEntity(Contract model) {
        ContractEntity ce = new ContractEntity();
        ce.setContractId(model.getId().getExtension());
        CVType cv = new CVType();
        cv.setCode(model.getType().getCode());
        ce.setType(cv);
        ce.setStartDate(model.getDatePeriod().getStart());
        ce.setEndDate(model.getDatePeriod().getEnd());

        return ce;
    }

    @Override
    public DeleteContractsByContractIdResponse deleteContractsByContractId(String contractId) throws Exception {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}